/**
 * Copyright (C) 2010-2016 eBusiness Information, Excilys Group
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed To in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ohosannotations.logger;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;

/**
 * Log 记录器
 *
 * @since 2021-07-19
 */
public class Logger {
    private final LoggerContext loggerContext;
    private final String name;

    /**
     * 构造参数
     *
     * @param loggerContext 上下文
     * @param name 字段名字
     */
    public Logger(LoggerContext loggerContext, String name) {
        this.loggerContext = loggerContext;
        this.name = name;
    }

    /**
     * 跟踪
     *
     * @param message 消息格式
     * @param args 可变参数
     */
    public void trace(String message, Object... args) {
        log(Level.TRACE, message, null, null, null, args);
    }

    /**
     * 调试
     *
     * @param message 消息格式
     * @param args 可变参数
     */
    public void debug(String message, Object... args) {
        log(Level.DEBUG, message, null, null, null, args);
    }

    /**
     * 信息
     *
     * @param message 消息格式
     * @param args 可变参数
     */
    public void info(String message, Object... args) {
        log(Level.INFO, message, null, null, null, args);
    }

    /**
     * 警告
     *
     * @param message 消息格式
     * @param args 可变参数
     */
    public void warn(String message, Object... args) {
        warn(null, message, args);
    }

    /**
     * 警告
     *
     * @param element 元素
     * @param message 消息格式
     * @param args 可变参数
     */
    public void warn(Element element, String message, Object... args) {
        log(Level.WARN, message, element, null, null, args);
    }

    /**
     * 警告
     *
     * @param element 元素
     * @param annotationMirror 注解反射
     * @param message 消息格式
     */
    public void warn(Element element, AnnotationMirror annotationMirror, String message) {
        log(Level.WARN, message, element, annotationMirror, null);
    }

    /**
     * 错误
     *
     * @param message 消息格式
     * @param args 可变参数
     */
    public void error(String message, Object... args) {
        error(null, null, message, args);
    }

    /**
     * 错误
     *
     * @param element 元素
     * @param message 消息格式
     * @param args 可变参数
     */
    public void error(Element element, String message, Object... args) {
        error(element, null, message, args);
    }

    /**
     * 错误
     *
     * @param thr 可抛异常
     * @param message 消息格式
     * @param args 可变参数
     */
    public void error(Throwable thr, String message, Object... args) {
        error(null, thr, message, args);
    }

    /**
     * 错误
     *
     * @param element 元素
     * @param thr 可抛异常
     * @param message 消息格式
     * @param args 可变参数
     */
    public void error(Element element, Throwable thr, String message, Object... args) {
        log(Level.ERROR, message, element, null, thr, args);
    }

    /**
     * 错误
     *
     * @param element 元素
     * @param annotationMirror 注解反射
     * @param message 消息格式
     */
    public void error(Element element, AnnotationMirror annotationMirror, String message) {
        log(Level.ERROR, message, element, annotationMirror, null);
    }

    /**
     * isLoggable
     *
     * @param level 水平
     * @return level
     */
    public boolean isLoggable(Level level) {
        return level.isGreaterOrEquals(loggerContext.getCurrentLevel());
    }

    /**
     * log
     *
     * @param level 水平
     * @param message 消息格式
     * @param element 元素
     * @param annotationMirror 注解反射
     * @param thr thr
     * @param args args
     */
    private void log(Level level, String message, Element element,
        AnnotationMirror annotationMirror, Throwable thr, Object... args) {
        if (!isLoggable(level)) {
            return;
        }
        loggerContext.writeLog(level, name, message, element, annotationMirror, thr, args);
    }
}
